/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package server.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import server.constants.GlobalConstants;
import server.constants.OrderConstants;
import server.dao.ClientDAO;
import server.dao.OrderDAO;
import server.dao.ProductDAO;
import server.domain.*;

/**
 *
 * @author fillipe
 */
public class OrderService {

    private OrderDAO orderDAO;
    ProductDAO pDAO;

    public OrderService() {
        this.orderDAO = new OrderDAO();
        this.pDAO = new ProductDAO();
    }

    public String insert(Long clientId, List<OrderItem> orderItems) {
        try {
            Order order = new Order(new ClientDAO().getById(clientId));

            for (OrderItem oi : orderItems) {
                Product p = pDAO.getById(oi.getId().getProduct().getId());
                oi.getId().setProduct(p);
                oi.setUnitPrice(p.getPrice());
                oi.setTotalItem(oi.getUnitPrice().multiply(new BigDecimal(oi.getQuantity())));
                if (oi.getQuantity() > 10) {
                    oi.setDiscount(oi.getTotalItem().multiply(new BigDecimal(0.02)));
                } else {
                    oi.setDiscount(BigDecimal.ZERO);
                }
            }
            orderDAO.save(order, orderItems);
            return OrderConstants.SAVED;
        } catch (Exception ex) {
            ex.printStackTrace();
            return GlobalConstants.ERROR_SAVE;
        }
    }

    public String updateOrderItem(Long idOrder, List<OrderItem> orderItems) {
        try {
            Order order = orderDAO.getById(idOrder);
            if (order.getDataProcessing() != null) {
                return OrderConstants.NOT_UPDATED_ORDER_PROCESSED;
            }
            List<OrderItem> oldItems = orderDAO.getItems(order);
            for (OrderItem item : refreshList(order, orderItems)) {
                int i = oldItems.indexOf(item);
                if (i >= 0) {
                    OrderItem o = oldItems.get(i);
                    o.setQuantity(item.getQuantity());
                    oldItems.set(i, o);
                } else if (item.getQuantity() > 0) {
                    oldItems.add(item);
                }
            }
            orderDAO.update(order, oldItems);
            return OrderConstants.UPDATED;
        } catch (Exception ex) {
            ex.printStackTrace();
            return GlobalConstants.ERROR_UPDATE;
        }
    }

    public String delete(Long idOrder) {
        try {
            Order order = orderDAO.getById(idOrder);
            orderDAO.deleteOrder(order);
            return OrderConstants.DELETED;
        } catch (Exception ex) {
            ex.printStackTrace();
            return GlobalConstants.ERROR_DELETE;
        }
    }

    public OrderDTO getByOrder(Long idOrder) {
        try {
            Order order = orderDAO.getById(idOrder);
            OrderDTO dto = new OrderDTO();
            dto.setId(idOrder);
            dto.setIssueDate(order.getIssueDate());
            dto.setProcessDate(order.getDataProcessing());
            dto.setTotal(order.getTotalOrder());
            dto.setQtd(orderDAO.getItems(order).size());
            return dto;
        } catch (Exception ex) {
            return null;
        }
    }

    public List<OrderDTO> getByClient(Long idClient) {
        List<OrderDTO> list = new ArrayList<OrderDTO>();
        try {
            Client client = new ClientDAO().getById(idClient);
            List<Order> orders = orderDAO.getOrdersByClient(client);
            for (Order o : orders) {
                OrderDTO aux = getByOrder(o.getId());
                if (aux != null) {
                    list.add(aux);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return list;
    }

    public String processOrder(Long idOrder) {
        boolean noStock = false;
        try {
            Order order = orderDAO.getById(idOrder);
            if (order.getDataProcessing() != null) {
                return OrderConstants.NOT_PROCESS_ORDER_PROCESSED;
            }
            List<OrderItem> list = orderDAO.getItems(order);
            for (OrderItem oi : list) {
                Product p = pDAO.getById(oi.getId().getProduct().getId());
                if (oi.getQuantity() > p.getStock()) {
                    oi.setQuantity(null);
                    oi.setTotalItem(BigDecimal.ZERO);
                    oi.setDiscount(BigDecimal.ZERO);
                    orderDAO.updateOrderItem(oi);
                    noStock = true;
                } else {
                    p.setStock(p.getStock() - oi.getQuantity());
                    pDAO.update(p);
                }
            }
            order.setDataProcessing(Calendar.getInstance().getTime());
            orderDAO.update(order);
            return noStock ? OrderConstants.PROCESSED + "\n" + OrderConstants.NO_STOCK_OBS : OrderConstants.PROCESSED;
        } catch (Exception ex) {
            ex.printStackTrace();
            return OrderConstants.ERROR_PROCESSING;
        }
    }

    private List<OrderItem> refreshList(Order order, List<OrderItem> list) {
        List<OrderItem> newList = new ArrayList<OrderItem>();
        for (OrderItem oi : list) {
            try {
                Product p = pDAO.getById(oi.getId().getProduct().getId());
                oi.getId().setProduct(p);
                oi.setUnitPrice(p.getPrice());
                oi.getId().setOrder(order);
                oi.setTotalItem(oi.getUnitPrice().multiply(new BigDecimal(oi.getQuantity())));
                if (oi.getQuantity() > 10) {
                    oi.setDiscount(oi.getTotalItem().multiply(new BigDecimal(0.02)));
                } else {
                    oi.setDiscount(BigDecimal.ZERO);
                }
                newList.add(oi);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return newList;
    }
}
